//
//  XDXMapView.m
//  location
//
//  Created by Dongxiang Xu on 2024/6/6.
//

#import "XDXMapView.h"
#import "TrackTool.h"
#import <QuartzCore/QuartzCore.h>

@interface XDXMapView ()

@property (nonatomic,strong) NSMutableSet<UIGestureRecognizer *> *xdx_activeGestures;
@property (nonatomic,strong) NSMutableSet<UIGestureRecognizer *> *xdx_hookedGestures;

@end

@implementation XDXMapView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hideMap) name:Noti_HideMap object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showMap) name:Noti_ShowMap object:nil];
        self.xdx_activeGestures = [NSMutableSet set];
        self.xdx_hookedGestures = [NSMutableSet set];
        [self xdx_installGestureHooksIfNeeded];
    }
    return self;
}
- (CGFloat)zoomLevel
{
    double mapWidth = self.frame.size.width;
    return log2(360 * mapWidth / 256.0 / self.region.span.longitudeDelta);
}

 - (void)setZoomLevel:(CGFloat)zoomLevel
{
    MKCoordinateSpan newRegionSpan = MKCoordinateSpanMake(360 / pow(2, zoomLevel), 360 / pow(2, zoomLevel));
    MKCoordinateRegion newRegion = MKCoordinateRegionMake(self.region.center, newRegionSpan);
    [self setRegion:newRegion animated:NO];
}

- (UIImage *)takePhoto
{
    UIGraphicsBeginImageContext(self.frame.size);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
            
    UIImage *imgeee = [UIImage imageWithCGImage:CGImageCreateWithImageInRect([viewImage CGImage], self.bounds)];
  
    return imgeee;
}

- (void)didMoveToWindow
{
    [super didMoveToWindow];
    [self xdx_installGestureHooksIfNeeded];
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    [self xdx_installGestureHooksIfNeeded];
}

- (void)xdx_installGestureHooksIfNeeded
{
    if (!self.xdx_hookedGestures) {
        self.xdx_hookedGestures = [NSMutableSet set];
    }
    if (!self.xdx_activeGestures) {
        self.xdx_activeGestures = [NSMutableSet set];
    }
    [self xdx_traverseAndHookGesturesInView:self];
}

- (void)xdx_traverseAndHookGesturesInView:(UIView *)view
{
    NSArray<UIGestureRecognizer *> *grs = view.gestureRecognizers;
    if (grs.count > 0) {
        for (UIGestureRecognizer *gr in grs) {
            if (![self.xdx_hookedGestures containsObject:gr]) {
                [gr addTarget:self action:@selector(xdx_gestureChanged:)];
                [self.xdx_hookedGestures addObject:gr];
            }
        }
    }
    for (UIView *subview in view.subviews) {
        [self xdx_traverseAndHookGesturesInView:subview];
    }
}

- (void)xdx_gestureChanged:(UIGestureRecognizer *)gr
{
    switch (gr.state) {
        case UIGestureRecognizerStateBegan:
            [self.xdx_activeGestures addObject:gr];
            self.isDrag = YES;
            break;
        case UIGestureRecognizerStateChanged:
            self.isDrag = YES;
            break;
        case UIGestureRecognizerStateEnded:
            self.isDrag = NO;
            break;
        case UIGestureRecognizerStateCancelled:
            self.isDrag = NO;
            break;
        case UIGestureRecognizerStateFailed: {
            if ([self.xdx_activeGestures containsObject:gr]) {
                [self.xdx_activeGestures removeObject:gr];
            }
            self.isDrag = NO;
            break;
        }
        default:
            break;
    }
}

- (void)rotateMapToNorthAnimated:(BOOL)animated
                      Coordinate:(CLLocationCoordinate2D)coordinate
{
    if (!self || coordinate.latitude<=0 || coordinate.longitude<=0) { return; }
    
    
    
    CGPoint point = [self convertCoordinate:coordinate toPointToView:self];
    
    if (CGRectContainsPoint(self.bounds, point)){
        MKMapCamera *oldCamera = self.camera;
        MKMapCamera *newCamera = [MKMapCamera cameraLookingAtCenterCoordinate:coordinate
                                                                 fromDistance:10000.0
                                                                        pitch:oldCamera.pitch
                                                                      heading:0.0];

        [CATransaction begin];
        [CATransaction setAnimationDuration:0.35];
        [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
       
        [self setCamera:newCamera animated:YES];
        [CATransaction commit];
    }else{
        double distance = [TrackTool distanceBetweenOrderByLatitudeA:self.centerCoordinate.latitude latitudeB:coordinate.latitude longitudeA:self.centerCoordinate.longitude longitudeB:coordinate.longitude];
        MKMapCamera *oldCamera = self.camera;
        MKMapCamera *newCamera = [MKMapCamera cameraLookingAtCenterCoordinate:coordinate
                                                                 fromDistance:10000.0+pow(distance, 1.1)*10000
                                                                        pitch:oldCamera.pitch
                                                                      heading:0.0];
        if (animated) {
            [CATransaction begin];
            [CATransaction setAnimationDuration:0.35];
            [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
           
            [self setCamera:newCamera animated:YES];
            [CATransaction commit];
            
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

                        
                MKMapCamera *oldCamera = self.camera;
                MKMapCamera *newCamera = [MKMapCamera cameraLookingAtCenterCoordinate:coordinate
                                                                         fromDistance:10000.0
                                                                                pitch:oldCamera.pitch
                                                                              heading:0.0];

                [CATransaction begin];
                [CATransaction setAnimationDuration:0.35];
                [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
               
                [self setCamera:newCamera animated:YES];
                [CATransaction commit];
                    
            });
        } else {
            [self setCamera:newCamera animated:NO];
        }
    }
}

- (void)hideMap
{
    self.hidden = YES;
}

- (void)showMap
{    
    self.hidden = NO;
}



@end
